package GMDPRE

type JacPoint struct {
	x BN
	y BN
	z BN
}

type AffPoint struct {
	x BN
	y BN
}

const Sm2CurveDigit = 8
const Sm2CurveSize = Sm2CurveDigit * 4
const Sm2AffPointSize = Sm2CurveSize * 2
const WindowD = 5

// Sm2Q Parameter Q: 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF
var Sm2Q = BN{
	0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE}

// Sm2QSub2 Parameter Q-2: 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFD
var Sm2QSub2 = BN{
	0xFFFFFFFD, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE}

// Sm2N Parameter N: 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123
var Sm2N = BN{
	0x39D54123, 0x53BBF409, 0x21C6052B, 0x7203DF6B,
	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE}

// Sm2NSub2 Parameter N-2: 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54121
var Sm2NSub2 = BN{
	0x39D54121, 0x53BBF409, 0x21C6052B, 0x7203DF6B,
	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE}

// Sm2A (a % q) in Montgomery domain
var Sm2A = BN{
	0xFFFFFFFC, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFC,
	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFB}

// Sm2B (b % q) in Montgomery domain
var Sm2B = BN{
	0x2BC0DD42, 0x90D23063, 0xE9B537AB, 0x71CF379A,
	0x5EA51C3C, 0x52798150, 0xBA20E2C8, 0x240FE188}

// Sm2JacG (G % q) in Montgomery domain
var Sm2JacG = JacPoint{
	BN{0xF418029E, 0x61328990, 0xDCA6C050, 0x3E7981ED, 0xAC24C3C3, 0xD6A1ED99, 0xE1C13B05, 0x91167A5E},
	BN{0x3C2D0DDD, 0xC1354E59, 0x8D3295FA, 0xC1F5E578, 0x6E2A48F8, 0x8D4CFB06, 0x81D735BD, 0x63CD65D4},
	BN{0x00000001, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001}}

// Sm2Mont1Q (1 % q) in Montgomery domain
var Sm2Mont1Q = BN{
	0x00000001, 0x00000000, 0xFFFFFFFF, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000001}

// Sm2McQ The montgomery const modulo q
const Sm2McQ DigT = 0x1

// Sm2RRQ rrq = r * r % q
var Sm2RRQ = BN{
	3, 2, 0xFFFFFFFF, 2, 1, 1, 2, 4}

// Sm2Mont1N (1 % n) in Montgomery domain
var Sm2Mont1N = BN{
	0xC62ABEDD, 0xAC440BF6, 0xDE39FAD4, 0x8DFC2094,
	0x00000000, 0x00000000, 0x00000000, 0x00000001}

// Sm2McN The montgomery const modulo n
const Sm2McN DigT = 0x72350975

// Sm2RRN rrq = r * r % n
var Sm2RRN = BN{
	0x7C114F20, 0x901192AF, 0xDE6FA2FA, 0x3464504A,
	0x3AFFE0D4, 0x620FC84C, 0xA22B3D3B, 0x1EB5E412}
